package com.qq.vip.mikuPy2001.bukkit.gui;

import com.qq.vip.mikuPy2001.bukkit.gui.privater.DefaultWindowsView;
import com.qq.vip.mikuPy2001.bukkit.gui.model.Module;
import com.qq.vip.mikuPy2001.bukkit.gui.util.ItemUtil;
import static com.qq.vip.mikuPy2001.bukkit.gui.util.ItemUtil.isEmpty;
import com.qq.vip.mikuPy2001.bukkit.gui.util.Message;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

/**
 * 通用的GUI类. 界面模板.
 *
 * @author MukiPy2001
 */
public class Windows {

    private static final HashSet<WindowsView> views = new HashSet<>();

    /**
     * 从配置文件获取 Windows 的工厂方法
     *
     * @param root 配置文件
     * @return 一个标准的Windows界面
     */
    public static Windows loadFromConfiguration(ConfigurationSection root) {
        Windows windows = new Windows();
        for (String key : root.getKeys(false))
            if (key.equalsIgnoreCase("title"))
                // 设置标题
                windows.setTitle(root.getString(key));
            else if (key.equalsIgnoreCase("Background"))
                // 设置背景
                if (root.isConfigurationSection(key))
                    windows.setBackgrounds(root.getConfigurationSection(key));
                else
                    Message.warn("I found Background, but it not is a Configuration, Please check it");
            else if (key.equalsIgnoreCase("line"))
                // 设置固定大小
                windows.setSize(root.getInt(key));
            else
                // 设置控件
                windows.setModule(Module.loadFromConfiguration(key, root.getConfigurationSection(key)));
        Message.debug("加载|Windows|: " + windows.getTitle());
        return windows;
    }

    /**
     * 关闭所有窗口. 本方法由本插件在被注销时自动调用. 无需手动调用
     */
    public static void close() {
        for (WindowsView view : views.toArray(new WindowsView[0]))
            view.close();
    }

    private String title;
    private int size = -1;
    private ItemStack background = new ItemStack(Material.THIN_GLASS);
    private final HashMap<Integer, ItemStack> backgrounds = new HashMap<>();
    private final LinkedHashMap<String, Module> modules = new LinkedHashMap<>();
    private final HashSet<ViewListener> listeners = new HashSet<>();

    /**
     * 创建一个空白界面,
     */
    public Windows() {
        listeners.add(new DefaultViewListener() {
            @Override
            @SuppressWarnings("element-type-mismatch")
            public void onClose(WindowsView wv) {
                views.remove(wv);
            }
        });
    }

    /**
     * 创建一个有着指定标题和指定 Module 的界面,
     *
     * @param Title 标题
     * @param is 多个 Module
     */
    @SuppressWarnings("OverridableMethodCallInConstructor")
    public Windows(String Title, Module... is) {
        this(Title);
        setModule(is);
    }

    /**
     * 创建一个有着指定标题界面,
     *
     * @param Title 标题
     */
    @SuppressWarnings("OverridableMethodCallInConstructor")
    public Windows(String Title) {
        this();
        Message.debug("new Windows: " + Title);
        setTitle(Title);
    }

    public Windows setTitle(String title) {
        this.title = title;
        return this;
    }

    public String getTitle() {
        return title;
    }

    public ItemStack getBackground() {
        return background;
    }

    public Windows setBackground(int index, ItemStack is) {
        if (!isEmpty(is))
            backgrounds.put(index, is);
        return this;
    }

    public Windows setBackgrounds(ItemStack is) {
        if (!isEmpty(is))
            background = is;
        return this;
    }

    public Windows setBackgrounds(ConfigurationSection background) {
        Set<String> keys = background.getKeys(false);
        for (String key : keys) {
            ConfigurationSection con = background.getConfigurationSection(key);
            ItemStack item = ItemUtil.loadFromConfiguration(con.getConfigurationSection("item"));
            if (!isEmpty(item))
                if (con.isString("index")) {
                    if (con.getString("index").equalsIgnoreCase("all"))
                        this.background = item;
                } else if (con.isList("index")) {
                    for (String string : con.getStringList("index")) {
                        try {
                            String[] split = string.split(",");
                            if (split.length == 1) {
                                backgrounds.put(Integer.valueOf(string), item);
                            } else if (split.length == 2) {
                                Integer line = Integer.valueOf(split[0].trim());
                                Integer lineIndex = Integer.valueOf(split[1].trim());
                                int index = (line - 1) * 9 + lineIndex - 1;
                                backgrounds.put(index, item);
                            }
                        } catch (Exception e) {
                            Message.warn("Background." + key + "'s index format error : " + string);
                        }
                    }
                } else
                    Message.warn("Background." + key + "'s index don't format");
            else
                Message.warn("Background." + key + " : no item or item is bad");
        }
        return this;
    }

    public HashMap<Integer, ItemStack> getBackgrounds() {
        return backgrounds;
    }

    public Windows setModule(Module is) {
        if (is != null)
            modules.put(is.getModuleID(), is);
        return this;
    }

    public Windows setModule(Module[] is) {
        for (Module i : is)
            if (is != null)
                modules.put(i.getModuleID(), i);
        return this;
    }

    public HashSet<ViewListener> getListeners() {
        return listeners;
    }

    public LinkedHashMap<String, Module> getModules() {
        return modules;
    }

    public Module getModule(String moduleID) {
        return modules.get(moduleID);
    }

    public Module[] getModule(int line, int lineIndex) {
        return getModule(line * 9 + lineIndex);
    }

    public Module[] getModule(int index) {
        if (index < 0 || index > 54)
            return new Module[0];
        ArrayList<Module> list = new ArrayList<>();
        for (Module value : modules.values())
            if (value.getIndex() == index)
                list.add(value);

        return list.toArray(new Module[0]);
    }

    public void setSize(int size) {
        if (size < 1)
            size = -1;
        else if (size > 6)
            size = 6;
        this.size = size;
    }

    public int getSize() {
        return size;
    }

    public WindowsView open(Player p) {
        WindowsView windowsView = new DefaultWindowsView(this, p);
        views.add(windowsView);
        return windowsView;
    }

    public void closeAll() {
        for (WindowsView view : views.toArray(new WindowsView[0]))
            if (view.getWindows() == this)
                view.close();
    }

    public void close(WindowsView view) {
        if (view.getWindows() == this)
            view.close();
    }

    public Windows addAllListener(ViewListener listener) {
        listeners.add(listener);
        return this;
    }
}
